package com.rhino.security.datasourceaccess;

import org.springframework.security.access.AccessDecisionManager;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.authentication.InsufficientAuthenticationException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;

import java.util.Collection;

/**
 * @ClassName MyAccessDecisionManager
 * @Description 这个自定义类的作用是获取当前登录用户的角色信息和FilterInvocationSecurityMetadataSource类返回的资源访问的相关信息进行比对，判断该用户是否具有访问当前URL的角色。
 * 用户是否有访问当前URL的所需要的角色。
 * @Author zyk
 * @Create 2021/7/12
 * @Version 1.0
 **/
public class MyAccessDecisionManager implements AccessDecisionManager {
    @Override
    public void decide(Authentication auth, Object object, Collection<ConfigAttribute> ca) throws AccessDeniedException, InsufficientAuthenticationException {
        Collection<? extends GrantedAuthority> auths = auth.getAuthorities();
        for (ConfigAttribute configAttribute : ca) {
            //URL没有配置权限直接，并且用户已登录可直接访问
            if ("ROLE_LOGIN".equals(configAttribute.getAttribute())
                    && auth instanceof UsernamePasswordAuthenticationToken) {
                return;
            }

            //判断当前用户是否具有访问当前菜单所需要的的角色-有一个即可
            for (GrantedAuthority authority : auths) {
                if (configAttribute.getAttribute().equals(authority.getAuthority())) {
                    return;
                }
            }
        }
        throw new AccessDeniedException("权限不足");
    }

    @Override
    public boolean supports(ConfigAttribute attribute) {
        return true;
    }

    @Override
    public boolean supports(Class<?> clazz) {
        return true;
    }
}
